package com.kx.center.service.impl;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.kx.center.common.Constant;
import com.kx.center.common.CustomHashMap;
import com.kx.center.entity.Account;
import com.kx.center.entity.Address;
import com.kx.center.entity.Food;
import com.kx.center.entity.StoreAppAccount;
import com.kx.center.entity.StoreInfo;
import com.kx.center.entity.query.QueryFoodCategory;
import com.kx.center.entity.query.QueryResult;
import com.kx.center.entity.shop.ShopOrder;
import com.kx.center.entity.shop.ShopOrderGoods;
import com.kx.center.entity.shop.ShopOrderPay;
import com.kx.center.mappers.AccountMapper;
import com.kx.center.mappers.FoodMapper;
import com.kx.center.mappers.MsgNoticeMapper;
import com.kx.center.mappers.ShopOrderMapper;
import com.kx.center.mappers.StoreAppAccountMapper;
import com.kx.center.service.ShopOrderService;
import com.kx.center.util.MD5Coder;
import com.kx.center.util.SerialNumber;
import com.kx.center.util.WXUtil;
import com.kx.center.util.ZFBUtil;

/**
 * Created by acmen on 16-1-12.
 *
 * 订单管理 1. 提交购物单 2. 审核 3. 取消审核 4. 用户付款 5. 发货 6. 退款 7. 收货
 */
@Service
public class ShopOrderServiceImpl implements ShopOrderService {

	@Autowired
	ShopOrderMapper shopOrderMapper;
	@Autowired
	StoreAppAccountMapper accountMapper;
	@Autowired
	MsgNoticeMapper msgNoticeMapper;
	@Autowired
	FoodMapper foodMapper;
	@Autowired
	AccountMapper mapper;

	@Override
	public ArrayList<HashMap<String, Object>> pushClientMessage(
			ShopOrder shopOrder) {
		
		List<StoreAppAccount> list = accountMapper
				.findAccountByStoreInfoId(shopOrder.getShopId());
		ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();
		for (StoreAppAccount s : list) {
			HashMap<String, Object> hashmap = new HashMap<String, Object>();
			hashmap.put("id", s.getId());
			hashmap.put("user_id", s.getUserId());
			data.add(hashmap);
		}
		
		return data;
	}
	
	@Override
	public List<String> mailRecipient(int companyId) {
		
		List<Account> account = mapper.findEmailByCompanyId(companyId);
		List<String> email = new ArrayList<String>();
		for(Account item : account){
			email.add(item.getEmail());
		}	
		return email;
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateOrderAndPayStatus(HashMap<String, Object> data, Integer channel) {
		
		CustomHashMap<String, Object> item = CustomHashMap.convert(data);
		
		ShopOrder shopOrder = new ShopOrder();
		shopOrder.setPayNum(item.getString("out_trade_no"));
		shopOrder.setOrderStatus(4);
		shopOrder.setId(item.getInteger("attach"));
		
		ShopOrderPay shopOrderPay = new ShopOrderPay();
		shopOrderPay.setPayNum(item.getString("out_trade_no"));
		shopOrderPay.setPayResult(data.toString());
		shopOrderPay.setType(channel);
		shopOrderPay.setStatus(2);
		
		shopOrderMapper.updateShopOrderFromPayment(shopOrder);
		shopOrderMapper.updateShopOrderPayByPayNum(shopOrderPay);
		
	}
	
	@Override
	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public String saveShopOrder(StoreAppAccount storeAppAccount, StoreInfo storeInfo, List<HashMap<String, Object>> json) {

		ShopOrder shopOrder = new ShopOrder();

		double total_price = 0;
		int total_num = 0;
		Integer addressId = 0;
		for (HashMap<String, Object> map : json) {
			CustomHashMap<String, Object> item = CustomHashMap.convert(map);
			if (item.getInteger("num") <= 0 || item.getInteger("num") == null) {

			} else {
				Food food = foodMapper.findFoodById(item.getInteger("id"));
				total_price += food.getGoodsPrice() * item.getInteger("num");
				total_num += item.getInteger("num");
				addressId = item.getInteger("addressId");
			}
		}

		String order_num = SerialNumber.getSN(SerialNumber.ORDER_NUM,
				storeAppAccount.getStoreInfoId());

		shopOrder.setShopId(storeAppAccount.getStoreInfoId());
		shopOrder.setAppAccountId(storeAppAccount.getId());
		shopOrder.setShopOwnerPhone(storeInfo.getMobile());
		shopOrder.setAppAccountUserName(storeAppAccount.getUsername());
		shopOrder.setShopName(storeInfo.getStoreName());
		shopOrder.setCompanyId(storeInfo.getCompanyId());
		shopOrder.setOrderNum(order_num);
		shopOrder.setGoodsNum(total_num);
		shopOrder.setGoodsAmount(total_price);
		shopOrder.setOrderStatus(1);
		shopOrder.setRefundStatus(0);
		shopOrder.setAddressId(addressId);
		shopOrderMapper.insertShopOrder(shopOrder);

		for (HashMap<String, Object> map : json) {
			CustomHashMap<String, Object> item = CustomHashMap.convert(map);
			Food food = foodMapper.findFoodById(item.getInteger("id"));
			ShopOrderGoods shopOrderGoods = new ShopOrderGoods();
			shopOrderGoods.setOrderId(shopOrder.getId());
			shopOrderGoods.setGoodsId(item.getInteger("id"));
			shopOrderGoods.setGoodsSku(food.getSkuId());
			shopOrderGoods.setGoodsName(food.getName());
			shopOrderGoods.setNum(item.getInteger("num"));
			shopOrderGoods.setGoodsPrice(food.getGoodsPrice());
			shopOrderGoods.setGoodsBasePrice(food.getGoodsPrice());
			shopOrderGoods.setGoodsPayPrice(food.getGoodsPrice());
			shopOrderGoods.setPicture(food.getPicture2());
			shopOrderMapper.insertShopOrderGoods(shopOrderGoods);
		}
		
		return order_num;
	}

	@Override
	public void cancelShopOrder(ShopOrder shopOrder) {
		shopOrderMapper.updateShopOrderFromCancel(shopOrder);		
	}
	
	@Override
	public void confirmShopOrder(ShopOrder shopOrder) {
		shopOrderMapper.updateShopOrderFromConfirm(shopOrder);
	}

	@Override
	public void paymentShopOrder(ShopOrder shopOrder) {
		shopOrderMapper.updateShopOrderFromPayment(shopOrder);
	}

	@Override
	public void rejectShopOrder(ShopOrder shopOrder) {
		shopOrderMapper.updateShopOrderFromReject(shopOrder);		
	}

	@Override
	public void deliverShopOrder(ShopOrder shopOrder) {
		shopOrderMapper.updateShopOrderFromDeliver(shopOrder);
	}

	@Override
	public void receiveShopOrder(ShopOrder shopOrder) {
		shopOrderMapper.updateShopOrderFromReceive(shopOrder);
	}
	
	@Override
	public ShopOrder findShopOrderById(Integer id) {
		return shopOrderMapper.findShopOrderById(id);
	}

	@Override
	public List<ShopOrderGoods> findShopOrderGoodsById(Integer id) {
		
		List<ShopOrderGoods> result = new ArrayList<ShopOrderGoods>();
		List<ShopOrderGoods> list = shopOrderMapper.findShopOrderGoodsById(id);
		for(ShopOrderGoods items : list){
			if(items.getNum() > 0){
				result.add(items);
			}
		}
		return result;
	}
	
	@Override
	public QueryResult queryShopOrder(QueryFoodCategory queryFoodCategory) {
		QueryResult result = new QueryResult();
		result.setPage(queryFoodCategory.getPage());
		result.setPageSize(queryFoodCategory.getPageSize());
		result.setTotalRecord(shopOrderMapper
				.findShopOrderCount(queryFoodCategory));
		result.setData(shopOrderMapper.findShopOrderList(queryFoodCategory));
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public HashMap<String, String> saveShopOrderPay(HttpServletRequest request, Integer id, Integer channel) throws Exception {	
		
		ShopOrder shopOrder = shopOrderMapper.findShopOrderById(id);
		
		String pay_num = SerialNumber.getSN(SerialNumber.PAY_NUM,
				shopOrder.getShopId());
		String params, sign, xml, result, prepay_id, serverIP;
		HashMap<String, String> map = new LinkedHashMap<String, String>();
		
		if(channel == 1){
			
			map.put("channel", "POS");
			map.put("out_trade_no", pay_num);
			map.put("body", "悸动奶茶结算中心");
			map.put("attach", id.toString());
			map.put("total_fee", String.valueOf(shopOrder.getGoodsAmount()));
			map.put("notify_url", Constant.WEB_MANAGER_URL + "/api/shopOrder/payment/wposPush");
			
		}else if(channel == 2){
			
			map.put("partner", Constant.partner);
			map.put("seller_id", Constant.partner);
			map.put("out_trade_no", pay_num);
			map.put("subject", shopOrder.getShopName());
			map.put("body", shopOrder.getShopName());
			map.put("total_fee", String.valueOf(shopOrder.getGoodsAmount()));
			map.put("notify_url", Constant.WEB_MANAGER_URL + "/api/shopOrder/payment/zfbPush");
			map.put("service", "mobile.securitypay.pay");
			map.put("payment_type", "1");
			map.put("_input_charset", Constant.input_charset);
			map.put("it_b_pay", "30m");
			
			params = ZFBUtil.concatParams(map);
	    	sign = ZFBUtil.sign(params, Constant.private_key, Constant.input_charset);
			map.clear();
			
			map.put("orderInfo", params + "&sign=" + "\""+ URLEncoder.encode (sign, "UTF-8" ) + "\""+"&sign_type="+"\""+"RSA"+"\"");
		}else if(channel == 3){
			
			serverIP  = WXUtil.getRemoteIpAddr(request);
			
			map.put("appid", Constant.appid_wx);
			map.put("mch_id", Constant.mch_id_wx);
			map.put("nonce_str", SerialNumber.getRandomString(16));
			map.put("body", shopOrder.getShopName());
			map.put("attach", id.toString());
			map.put("out_trade_no", pay_num);
			map.put("total_fee", String.valueOf((int)(shopOrder.getGoodsAmount()*100)));
			map.put("spbill_create_ip", serverIP);
			map.put("notify_url", Constant.WEB_MANAGER_URL + "/api/shopOrder/payment/wzfPush");
			map.put("trade_type", "APP");
			
			params = WXUtil.concatParams(map) + "&key=" + Constant.key_wx + "";
			sign = MD5Coder.encode(params).toUpperCase();
			
			map.put("sign", sign);
			
			xml = WXUtil.mapToXml(map, "xml");
			map.clear();
			result = WXUtil.post(Constant.pay_url_wx, xml);
			HashMap<String, Object> maps = WXUtil.xmlToMap(result);
			CustomHashMap<String, Object> item = CustomHashMap.convert(maps);
			
			prepay_id = item.getString("prepay_id");
			
			map.put("appid", Constant.appid_wx);
			map.put("partnerid", Constant.mch_id_wx);
			map.put("prepayid", prepay_id);
			map.put("package", "Sign=WXPay");
			map.put("noncestr", SerialNumber.getRandomString(16));
			map.put("timestamp", String.valueOf((int)(System.currentTimeMillis()/1000)));
			
			params = WXUtil.concatParams(map) + "&key=" + Constant.key_wx + "";
			sign = MD5Coder.encode(params).toUpperCase();
			
			map.put("sign", sign);
			
		}else{
			map.put("error", "支付渠道参数错误!");
		}
		
		ShopOrderPay shopOrderPay = new ShopOrderPay();
		shopOrderPay.setShopId(shopOrder.getShopId());
		shopOrderPay.setOrderId(shopOrder.getId());
		shopOrderPay.setOrderNum(shopOrder.getOrderNum());
		shopOrderPay.setPayNum(pay_num);
		shopOrderPay.setAmount(shopOrder.getGoodsAmount());
		shopOrderPay.setPayPostData(map.toString());
		shopOrderPay.setType(channel);
		shopOrderPay.setStatus(1);
		shopOrderMapper.insertShopOrderPay(shopOrderPay);
		
		return map;
	}
	
	@Override
	public List<ShopOrderPay> findShopOrderPayPN() {
		return shopOrderMapper.findShopOrderPayPN();
	}

	@Override
	public void updatePayStatusByPayNum(ShopOrderPay shopOrderPay) {
		shopOrderMapper.updateShopOrderPayByPayNum(shopOrderPay);		
	}

	@Override
	public ShopOrderPay findShopOrderPayByPayNum(String payNum) {
		return shopOrderMapper.findShopOrderPayByPayNum(payNum);
	}

	@Override
	public Address findShopOrderAddress(Integer id) {
		// 查询订单对应的收货地址
		
		return shopOrderMapper.findShopOrderAddress(id);
	}

	@Override
	public Address getOrderAddress(Integer orderId) {
		
		return shopOrderMapper.getOrderAddress(orderId);
	}

}
